package dashboard;

import java.io.IOException;
import java.io.ObjectStreamException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.*;

@SuppressWarnings("serial")

public class StatisticsServlet extends HttpServlet {

	private User currentUser;
	private HttpSession session;
	private HttpServletRequest req;
	private HttpServletResponse resp;
	

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		this.req = req;
		this.resp = resp;
		session = req.getSession();
		currentUser = (User) session.getAttribute("user");
		currentUser = UserRegistry.getInstance().getUserById(currentUser.getId());

		if(session.getAttribute("rNumber")!=null) {
			String userName = (String) session.getAttribute("rNumber");
			if(UserRegistry.getInstance().getUserByUserName(userName)!=null){
				currentUser = UserRegistry.getInstance().getUserByUserName(userName);
			}
			else if(UserRegistry.getInstance().getUserByNumber(userName)!=null){
				currentUser = UserRegistry.getInstance().getUserByNumber(userName);
			}
		}

		if(req.getParameter("rNumber")!=null){
			User requestedUser = UserRegistry.getInstance().getUserByNumber(req.getParameter("rNumber"));
			if(requestedUser!=null){
				session.setAttribute("rNumber",requestedUser.getUserName());
			}
			
			else{
				ArrayList<String> errors = new ArrayList<String>();
				errors.add("This user does not exist.");
				session.setAttribute("errors",errors);
			}
			resp.sendRedirect("statistics.jsp");	
		}
		else if(req.getParameter("live")!=null) {
			getLive();
		}
		else if(req.getParameter("course")!=null) {
			getCourse();
		}
		else if(req.getParameter("month")!=null) {
			getMonth();
		}
		else if(req.getParameter("global")!=null) {
			getGlobal();
		}
		else if(req.getParameter("milestones")!=null) {
			getMilestones();
		}
		else{
			List<String> errors = new ArrayList<String>();
			errors.add("Prepare for selfdestruction :)");
			session.setAttribute("errors", errors);
			resp.sendRedirect("statistics.jsp");
		}
	}
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		this.req = req;
		this.resp = resp;
		session = req.getSession();
		currentUser = (User) session.getAttribute("user");
		currentUser = UserRegistry.getInstance().getUserById(currentUser.getId());

		if(session.getAttribute("rNumber")!=null) {
			String userName = (String) session.getAttribute("rNumber");
			if(UserRegistry.getInstance().getUserByUserName(userName)!=null){
				currentUser = UserRegistry.getInstance().getUserByUserName(userName);
			}
			else if(UserRegistry.getInstance().getUserByNumber(userName)!=null){
				currentUser = UserRegistry.getInstance().getUserByNumber(userName);
			}
		}

		if(req.getParameter("rNumber")!=null){
			User requestedUser = UserRegistry.getInstance().getUserByNumber(req.getParameter("rNumber"));
			if(requestedUser!=null){
				session.setAttribute("rNumber",requestedUser.getUserName());
			}
			
			else{
				ArrayList<String> errors = new ArrayList<String>();
				errors.add("This user does not exist.");
				session.setAttribute("errors",errors);
			}
			resp.sendRedirect("statistics.jsp");	
		}
		else if(req.getParameter("live")!=null) {
			getLive();
		}
		else if(req.getParameter("course")!=null) {
			getCourse();
		}
		else if(req.getParameter("month")!=null) {
			getMonth();
		}
		else if(req.getParameter("global")!=null) {
			getGlobal();
		}
		else if(req.getParameter("milestones")!=null) {
			getMilestones();
		}
		else{
			List<String> errors = new ArrayList<String>();
			errors.add("Prepare for selfdestruction :)");
			session.setAttribute("errors", errors);
			resp.sendRedirect("statistics.jsp");
		}
	}

	private void getLive() throws IOException {
		Map<String,Activity> liveMap = Statistics.getLiveStudents();
		Map<String, Double> typeMap = new LinkedHashMap<String,Double>();
		Map<String, Double> courseMap = new LinkedHashMap<String,Double>();
		if(liveMap.isEmpty()){
			ArrayList<String> errors = new ArrayList<String>();
			errors.add("No one is currently tracking an activity");
			session.setAttribute("errors", errors);
			resp.sendRedirect("statistics.jsp");
		}
		else{
			if(req.getParameter("type")==null){
			Iterator it = liveMap.entrySet().iterator();
			typeMap.put("Studying", 0.0);
			typeMap.put("Other", 0.0);
			typeMap.put("Lecture", 0.0);
			typeMap.put("Worksession", 0.0);
			
			while (it.hasNext()) {
				Map.Entry pairs = (Map.Entry)it.next();
				Activity activity = (Activity) pairs.getValue();
				double value = typeMap.get(activity.getType());
				typeMap.put(activity.getType(), value+1);
				
					  }
				
			
			
			session.setAttribute("result", typeMap);
			resp.sendRedirect("statistics.jsp?s=live");
		}
			else{
				
			String type = req.getParameter("type");
			List<Long> courseIds = currentUser.getCourses();	
			for(long courseId : courseIds){
				courseMap.put(CourseRegistry.getInstance().getCourseName(courseId), 0.0);
			}
				
			Iterator it = liveMap.entrySet().iterator();
			CourseRegistry cr = CourseRegistry.getInstance();
			while (it.hasNext()) {
				Map.Entry pairs = (Map.Entry)it.next();
				Activity activity = (Activity) pairs.getValue();
				if(activity.getType().equals(type)){
				double value = courseMap.get(cr.getCourseName(activity.getCourseId()));
				courseMap.put(cr.getCourseName(activity.getCourseId()), value+1);
				}
				
			 }	
			session.setAttribute("result", courseMap);
			resp.sendRedirect("statistics.jsp?s=live&type="+type);	
			}
		}
	}
	private void getCourse() throws IOException {
		String courseName = req.getParameter("courseName");
		if(courseName==null){
			resp.sendRedirect("statistics.jsp?s=course");
		}
		else{
			Map<String, Double> totalDuration = Statistics.getTotalDurationPerType(courseName, currentUser);
			if(totalDuration == null){
				ArrayList<String> errors = new ArrayList<String>();
				errors.add("Server encountered a problem with your durations.");
				session.setAttribute("errors", errors);
				resp.sendRedirect("statistics.jsp");
			}
			else{
				session.setAttribute("totalDuration", totalDuration);
			}

			Map<String, Double> userDuration = Statistics.getUserDurationPerType(courseName, currentUser);
			if(userDuration == null){
				ArrayList<String> errors = new ArrayList<String>();
				errors.add("Server encountered a problem with your durations.");
				session.setAttribute("errors", errors);
				resp.sendRedirect("statistics.jsp");
			}
			else{
				session.setAttribute("userDuration", userDuration);
			}

			Map<String, Double> userWeekDuration = Statistics.getTimeOfUserPerWeek(courseName, currentUser);
			session.setAttribute("userWeekDuration", userWeekDuration);

			Map<String, Double> allWeekDuration = Statistics.getTimeOfAllUsersPerWeek(courseName);
			session.setAttribute("allWeekDuration", allWeekDuration);

			Map<String, Double> userMonthDuration = Statistics.getDurationPerDayThisMonthUser(currentUser, courseName);
			session.setAttribute("userMonthDuration", userMonthDuration);

			Map<String, Double> allMonthDuration = Statistics.getDurationPerDayPerMonthAllUsers(courseName);
			session.setAttribute("allMonthDuration", allMonthDuration);

			Map<String, Double> userYearDuration = Statistics.getDurationPerMonthCurrentUser(courseName, currentUser);
			session.setAttribute("userYearDuration", userYearDuration);

			Map<String, Double> allYearDuration = Statistics.getDurationPerMonthAllUsers(courseName);
			session.setAttribute("allYearDuration", allYearDuration);

			List<Double> courseAppreciation = Statistics.getAppreciations(courseName, currentUser);
			session.setAttribute("courseAppreciation", courseAppreciation);

			resp.sendRedirect("statistics.jsp?s=course&course="+courseName);
		}
	}

	private void getMonth() throws IOException {
		String monthName = req.getParameter("monthName");
		if(monthName==null){
			resp.sendRedirect("statistics.jsp?s=month");
		}
		else{
			List<String> monthNames = Statistics.getCats(monthName);
			session.setAttribute("monthNames", monthNames);

			Map<String, Double[]> userMonthMap = Statistics.getUserMonthMap(currentUser, monthName);
			session.setAttribute("userMonthMap", userMonthMap);

			Map<String, Double[]> averageMonthMap = Statistics.getAverageMonthMap(monthName);
			session.setAttribute("averageMonthMap", averageMonthMap);


			Map<String, Double> monthStats = Statistics.getMonthStats(currentUser, monthName);
			session.setAttribute("monthStats", monthStats);

			Map<String, Double> userTypeMonth = Statistics.getUserTypeMonth(currentUser, monthName);
			session.setAttribute("userTypeMonth", userTypeMonth);

			Map<String, Double> averageTypeMonth = Statistics.getAverageTypeMonth(monthName);
			session.setAttribute("averageTypeMonth", averageTypeMonth);

			resp.sendRedirect("statistics.jsp?s=month&m="+monthName);
		}
	}

	private void getGlobal() throws IOException {

		Map<String, Double> meanDurations = Statistics.getAverageDurationPerCourse(currentUser);
		session.setAttribute("allActivities", meanDurations);

		Map<String, Double> userDurations = Statistics.getTotalDurationPerCourse(currentUser, currentUser);
		session.setAttribute("userActivities", userDurations);

		Map<String, Double> allCourseAppreciations = Statistics.getAverageAppreciationPerCourse(currentUser);
		session.setAttribute("coursesAppreciation", allCourseAppreciations);

		Map<String, Double> allCourses = Statistics.getStudyPointsPerCourse(currentUser);
		session.setAttribute("allCourses", allCourses);

		Map<String, Double> userCoursesAppreciation = Statistics.getUserAppreciationPerCourse(currentUser, currentUser);
		session.setAttribute("userCoursesAppreciation", userCoursesAppreciation);

		resp.sendRedirect("statistics.jsp?s=global");
	}

	private void getMilestones() throws IOException {
		Map<String, Double> milestones = Statistics.getUserMilestones(currentUser);
		session.setAttribute("milestones", milestones);

		Map<String, Double> allMilestones = Statistics.getAllUsersMilestones();
		session.setAttribute("allMilestones", allMilestones);

		resp.sendRedirect("statistics.jsp?s=milestones");
	}
}
